package com.example.shop.fgo.task.download.controller;

import android.content.Intent;
import android.text.TextUtils;

import com.example.shop.fgo.Constant;
import com.example.shop.fgo.base.YBaseApp;
import com.example.shop.fgo.entity.FileListEntity;
import com.example.shop.fgo.net.FileListServe;
import com.example.shop.fgo.task.common.controller.TaskController;
import com.example.shop.fgo.task.common.controller.TaskMsg;
import com.example.shop.fgo.task.common.controller.UpdatePart;
import com.example.shop.fgo.task.common.model.TaskState;
import com.example.shop.fgo.task.download.model.DownloadDaoConfig;
import com.example.shop.fgo.task.download.model.DownloadTask;
import com.example.shop.fgo.utils.CookieUtil;
import com.example.shop.fgo.utils.SavePathUtil;
import com.example.shop.library.net.NetJsonUtil;

import org.greenrobot.eventbus.EventBus;
import org.xutils.DbManager;
import org.xutils.ex.DbException;
import org.xutils.x;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Created by Administrator on 2017/2/20.
 */

public class DownloadController implements TaskController<DownloadTask>{
    private DbManager.DaoConfig mDaoConfig;
    public DownloadController() {

        mDaoConfig= DownloadDaoConfig.getDownloadDaoConfig();
    }
    /**
     * 添加一堆任务到下载队列
     * @param dataEntities  目标任务们
     * @param pathEntities  所处路径PathEntity集合
     */
    public void addTasksToQueue(List<FileListEntity.DataEntity> dataEntities, List<FileListEntity.PathEntity> pathEntities){
        for (FileListEntity.DataEntity dataEntity : dataEntities) {
            if (TextUtils.isEmpty(dataEntity.getCid())) {
                //添加一个文件
                addFileTaskToQueue(dataEntity,pathEntities);
            }else{
                //文件夹
                addDirTaskToQueue(dataEntity,pathEntities);
            }
        }
        startTasks();
    }
    /**
     * 添加一个文件夹里的全部东西到下载队列中，如果文件夹有子文件夹，那么就继续添加子文件夹里的全部东西到下载队列中，循环往复。。
     * @param dataEntity
     * @param pathEntities
     */
    private void addDirTaskToQueue(FileListEntity.DataEntity dataEntity, final List<FileListEntity.PathEntity> pathEntities) {
        Map<String, Object> mMapRefreshParams = new HashMap<>();
        mMapRefreshParams.put("ct", "list");
        mMapRefreshParams.put("aid", "1");
        mMapRefreshParams.put("o", Constant.SORT_USER_PTIME);
        mMapRefreshParams.put("asc", "0");
        mMapRefreshParams.put("offset", "0");
        mMapRefreshParams.put("limit", "60");
        mMapRefreshParams.put("cid", dataEntity.getCid());
        FileListServe fileListServe = NetJsonUtil.getRetrofit(Constant.BASE_URL, FileListServe.class);
        Call<FileListEntity> call = fileListServe.requestFiles(mMapRefreshParams, CookieUtil.getCookie());

        call.enqueue(new Callback<FileListEntity>() {
            @Override
            public void onResponse(Call<FileListEntity> call, Response<FileListEntity> response) {
                FileListEntity fileListEntity = response.body();
                List<FileListEntity.DataEntity> dataEntities = fileListEntity.getData();
                List<FileListEntity.PathEntity> pathEntities1 = fileListEntity.getPath();
                addTasksToQueue(dataEntities,pathEntities);
            }

            @Override
            public void onFailure(Call<FileListEntity> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }

    private void addFileTaskToQueue(FileListEntity.DataEntity dataEntity,List<FileListEntity.PathEntity> pathEntities) {
        DownloadTask downloadTask=new DownloadTask();
        //给下载任务设置各项数据
        downloadTask.setFid(dataEntity.getFid());
        downloadTask.setName(dataEntity.getN());
        downloadTask.setTotalSize((int) dataEntity.getS());
        downloadTask.setSavaPath(SavePathUtil.getDirPath(pathEntities)+dataEntity.getN());
        downloadTask.setSha1(dataEntity.getSha1());
        downloadTask.setTime(System.currentTimeMillis());
        downloadTask.setU(dataEntity.getU());
        downloadTask.setIco(dataEntity.getIco());
        //对下载文件对象的任务添加完后 存到数据库中
        try {
            x.getDb(mDaoConfig).save(downloadTask);
        } catch (DbException e) {
            e.printStackTrace();
        }
    }
    /**
     * 设置当前下载任务的下载链接
     * @param downloadTask
     * @param url
     */
    protected void updateDownloadTaskUrl(DownloadTask downloadTask,String url){
        downloadTask.setUrl(url);

        try {
            x.getDb(mDaoConfig).update(downloadTask,"url");
        } catch (DbException e) {
            e.printStackTrace();
        }
    }

    protected void updateDownloadTaskState(DownloadTask downloadTask,int newState){
        downloadTask.setState(newState);
        try {
            x.getDb(mDaoConfig).update(downloadTask,"state");
        } catch (DbException e) {
            e.printStackTrace();
        }
        TaskMsg downloadMsg=TaskMsg.obtain();
        downloadMsg.mUpdatePart= UpdatePart.STATE;
        downloadMsg.mTask=downloadTask;
        EventBus.getDefault().post(downloadMsg);
    }

    /**
     *
     * @param downloadTask 哪个任务
     * @param newSize       又下载了多少
     */
    protected void updateDownloadTaskSize(DownloadTask downloadTask,int newSize){
        downloadTask.setNowSize(downloadTask.getNowSize()+newSize);
        try {
            x.getDb(mDaoConfig).update(downloadTask,"nowSize","nowSizeStr");
        } catch (DbException e) {
            e.printStackTrace();
        }
        TaskMsg downloadMsg=TaskMsg.obtain();
        downloadMsg.mUpdatePart=UpdatePart.SIZE;
        downloadMsg.mTask=downloadTask;
        EventBus.getDefault().post(downloadMsg);
    }
    /**
     *
     * @param downloadTask 哪个任务
     * @param newSpeed       下载速度
     */
    protected void updateDownloadTaskSpeed(DownloadTask downloadTask,String newSpeed){
        downloadTask.setSpeed(newSpeed);
        try {
            x.getDb(mDaoConfig).update(downloadTask,"speed");
        } catch (DbException e) {
            e.printStackTrace();
        }
        TaskMsg downloadMsg=TaskMsg.obtain();
        downloadMsg.mUpdatePart=UpdatePart.SPEED;
        downloadMsg.mTask=downloadTask;
        EventBus.getDefault().post(downloadMsg);
    }
    /**
     * 重置下载量为0
     */

    protected void resetDownSize(DownloadTask downloadTask) {
        downloadTask.setNowSize(0);
        File file=new File(downloadTask.getSavaPath());
        file.delete();
        try {
            x.getDb(mDaoConfig).update(downloadTask, "nowSize", "nowStr");
        } catch (DbException e) {
            e.printStackTrace();
        }
        TaskMsg downloadMsg = TaskMsg.obtain();
        downloadMsg.mUpdatePart = UpdatePart.SIZE;
        downloadMsg.mTask = downloadTask;
        EventBus.getDefault().post(downloadMsg);
    }

    /**
     * 用于正在执行的下载任务列表
     * @return
     */
    public List<DownloadTask> getTasksUnDone(){
        try {
            return x.getDb(mDaoConfig).selector(DownloadTask.class).where("state","<>", TaskState.TASK_STATE_DONE)
                    .and("state","<>",TaskState.TASK_STATE_CANCEL).findAll();
        } catch (DbException e) {
            e.printStackTrace();
        }

        return null;

    } /**
     * 用于已完成的下载任务列表
     * @return
     */
    public List<DownloadTask> getTasksDone(){
        try {
            return x.getDb(mDaoConfig).selector(DownloadTask.class).where("state","==", TaskState.TASK_STATE_DONE)
                    .findAll();
        } catch (DbException e) {
            e.printStackTrace();
        }

        return null;

    }
    /**
     * 找到一个处于排队的下载任务，我们把它拿去执行下载动作
     * @return 处于排队的下载任务
     */
    protected DownloadTask getDownloadTaskWait(){
        try {
            return x.getDb(mDaoConfig).selector(DownloadTask.class).where("state","=", TaskState.TASK_STATE_WAIT).findFirst();
        } catch (DbException e) {
            e.printStackTrace();
        }
        return null;

    }
    //开始执行下载
    public void startTasks(){
        Intent intent=new Intent(YBaseApp.mContextGlobal,DownloadService.class);
        YBaseApp.mContextGlobal.startService(intent);
    }
    /*
    删除指定任务
     */
    public void cancelTask(DownloadTask downloadTask){
        File file=new File(downloadTask.getSavaPath());
        file.delete();
        updateDownloadTaskState(downloadTask,TaskState.TASK_STATE_CANCEL);
    }
    /**
     *
     * 暂停指定任务
     *
     * @param downloadTask
     *
     */
    public void pauseTask(DownloadTask downloadTask){


        updateDownloadTaskState(downloadTask,TaskState.TASK_STATE_PAUSE);

    }

    /**
     *
     * 暂停指定任务
     *
     * @param downloadTask
     *
     */

    public void resumeTask(DownloadTask downloadTask){

        updateDownloadTaskState(downloadTask,TaskState.TASK_STATE_WAIT);
        startTasks();

    }
    /*
    * 判断某个任务是否被删除
    * */
    protected boolean hasCanceled(DownloadTask downloadTask){
        try {
            DownloadTask task = x.getDb(mDaoConfig).findById(DownloadTask.class, downloadTask.getId());
            //如果判断的任务为空，数据库中没有了这个任务的数据了---不用再继续了
            if (task==null) {
                return true;
            }
            if (task.getState()== TaskState.TASK_STATE_CANCEL) {
                return true;
            }
            return false;
        } catch (DbException e) {
            e.printStackTrace();
        }
        return false;
    }
    /**
     * 判断某个任务是否被暂停
     *
     */

    protected boolean haspaused(DownloadTask downloadTask){
        try {
            DownloadTask task = x.getDb(mDaoConfig).findById(DownloadTask.class, downloadTask.getId());

            if (task==null) {
                return true;
            }

            if (task.getState()== TaskState.TASK_STATE_PAUSE) {
                return true;
            }
            return false;
        } catch (DbException e) {
            e.printStackTrace();
        }
        return false;
    }
    /**
     * 查询当前正在执行的全部任务的存储需求
     */
    public int getTotalSizeIngRequire() {
        try {
            //把正在下载的任务全部找出来
            List<DownloadTask> downloadTasks =
                    x.getDb(mDaoConfig).
                            selector(DownloadTask.class).
                            where("state", "=", TaskState.TASK_STATE_ING).
                            findAll();

            if (downloadTasks == null) {
                return 0;
            }
            int total = 0;
            for (DownloadTask downloadTask : downloadTasks) {
                total += (downloadTask.getTotalSize() - downloadTask.getNowSize());
            }
            return total;
        } catch (DbException e) {
            e.printStackTrace();
        }
        return 0;
    }
}
